package com.kira.scaffoldmvc.CommonPool;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;

import static com.kira.scaffoldmvc.CommonPool.RtaProxyContextHolder.RTA_PROXY_CONTENT_POOL;

/**
 * 对象池简易监控
 */
@Component
public class SysMonitorConfig {

    // 滑动窗口配置
    private final ArrayList<Integer> list = new ArrayList<>();

    //最大修改范围是原来对象池范围的两倍或三倍
    private final Integer minIdle = 600;
    private final Integer maxIdle = 1800;
    private final Integer maxTotal = 3000;

    //每五分钟打印一次对象池状态,并将当前活跃对象数放进List中
    @Scheduled(cron = "0 0/5 * * * *")
    public void monitorContextPool() {
        RtaProxyContextHolder.printPoolStatus();
        list.add(RTA_PROXY_CONTENT_POOL.getNumActive());
    }

    //每半小时统计后5个滑动窗口里的对象数,如果平均活跃对象数大于当前对象池中配置的最大空闲对象数,则更新
    @Scheduled(cron = "0 0/30 * * * *")
    public void adjustContextPool() {
        Integer averageIdle = 0;
        Integer sum = 0;
        for (int i = list.size() - 1, j = 0; j < 6; i--, j++) {
            sum += list.get(i);
        }
        averageIdle = sum / 6;
        if(averageIdle>RTA_PROXY_CONTENT_POOL.getMaxIdle() && RTA_PROXY_CONTENT_POOL.getMaxIdle()!=maxIdle){
            //平均活跃数大于对象池最大空闲对象数,则进行更新,如果对象池最大空闲对象数已经更新到了可达到的最大值,那么就没必要更新
            int minSize = 200;
            if(averageIdle/2>RTA_PROXY_CONTENT_POOL.getMaxIdle()){//如果平均活跃数/2大于最小活跃数,则直接更新成允许范围的最大值
                minSize=minIdle;
            }
            int maxSize = RTA_PROXY_CONTENT_POOL.getMaxIdle();
            while(maxSize<averageIdle){
                maxSize += 600;
            }
            if(maxSize>maxIdle){
                maxSize=maxIdle;
            }
            //更新对象池配置
            RtaProxyContextHolder.adjustPoolConfig(maxTotal,maxSize,minSize);
        }
    }

}